#ifndef _WIDGET_H_
#define _WIDGET_H_

#include <functional>
#include <string>
#include <SECore/Event.h>
#include <SEUi/Interactor/Interactor.h>
#include <glm/glm.hpp>
#include <SECore/Signal.h>
#include <SECore/EnableEventHandle.h>

namespace SEngine
{
    enum WindowFlag 
    {
        WindowFlags_None                   = 0,
        WindowFlags_NoTitleBar             = 1 << 0,   // Disable title-bar
        WindowFlags_NoResize               = 1 << 1,   // Disable user resizing with the lower-right grip
        WindowFlags_NoMove                 = 1 << 2,   // Disable user moving the window
        WindowFlags_NoScrollbar            = 1 << 3,   // Disable scrollbars (window can still scroll with mouse or programmatically)
        WindowFlags_NoScrollWithMouse      = 1 << 4,   // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set.
        WindowFlags_NoCollapse             = 1 << 5,   // Disable user collapsing window by double-clicking on it. Also referred to as Window Menu Button (e.g. within a docking node).
        WindowFlags_AlwaysAutoResize       = 1 << 6,   // Resize every window to its content every frame
        WindowFlags_NoBackground           = 1 << 7,   // Disable drawing background color (WindowBg, etc.) and outside border. Similar as using SetNextWindowBgAlpha(0.0f).
        WindowFlags_NoSavedSettings        = 1 << 8,   // Never load/save settings in .ini file
        WindowFlags_NoMouseInputs          = 1 << 9,   // Disable catching mouse, hovering test with pass through.
        WindowFlags_MenuBar                = 1 << 10,  // Has a menu-bar
        WindowFlags_HorizontalScrollbar    = 1 << 11,  // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section.
        WindowFlags_NoFocusOnAppearing     = 1 << 12,  // Disable taking focus when transitioning from hidden to visible state
        WindowFlags_NoBringToFrontOnFocus  = 1 << 13,  // Disable bringing window to front when taking focus (e.g. clicking on it or programmatically giving it focus)
        WindowFlags_AlwaysVerticalScrollbar= 1 << 14,  // Always show vertical scrollbar (even if ContentSize.y < Size.y)
        WindowFlags_AlwaysHorizontalScrollbar=1<< 15,  // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
        WindowFlags_AlwaysUseWindowPadding = 1 << 16,  // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient)
        WindowFlags_NoNavInputs            = 1 << 18,  // No gamepad/keyboard navigation within the window
        WindowFlags_NoNavFocus             = 1 << 19,  // No focusing toward this window with gamepad/keyboard navigation (e.g. skipped by CTRL+TAB)
        WindowFlags_UnsavedDocument        = 1 << 20,  // Display a dot next to the title. When used in a tab/docking context, tab is selected when clicking the X + closure is not assumed (will wait for user to stop submitting the tab). Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar.
        WindowFlags_NoDocking              = 1 << 21,  // Disable docking of this window
        WindowFlags_HideClose              = 1 << 22,  // Hide close button


        WindowFlags_NoNav                  = WindowFlags_NoNavInputs | WindowFlags_NoNavFocus,
        WindowFlags_NoDecoration           = WindowFlags_NoTitleBar | WindowFlags_NoResize | WindowFlags_NoScrollbar | WindowFlags_NoCollapse,
        WindowFlags_NoInputs               = WindowFlags_NoMouseInputs | WindowFlags_NoNavInputs | WindowFlags_NoNavFocus,
    };

    class Widget : public EnableEventHandle
    {
    public:
        Widget();
        virtual ~Widget() = default;

        Widget & SetTitle(const std::string & name) { m_name = name; return *this; }
        std::string GetTitle() { return m_name; }
        Widget & SetWindowFlag(int flag, bool value);
        glm::ivec4 GetRect() { return m_rect; }
        virtual void Update(int delta);
        virtual void OnEvent(EventPtr event);
        void SetInteractor(std::unique_ptr<Interactor> && interactor) { m_interactor = std::move(interactor); }
        std::unique_ptr<Interactor> & GetInteractor() { return m_interactor; }
        void SetVisiable(bool value) { m_open = value; }
        bool IsHoveredWindow();


    protected:
        virtual void BeginUpdate() {}
        virtual void UpdateImpl(int delta) {}
        virtual void EndUpdate() {}

    public:
        Signal<> SignalClose;
        
    protected:
        std::string m_name;
        bool m_open;
        int m_windowFlags;
        bool m_isFocused;
        std::unique_ptr<Interactor> m_interactor;
        glm::ivec4 m_rect;
    };
} // namespace SEngine



#endif